package com.lensyn.generator.plugins;

import com.lensyn.generator.domain.MsgKey;
import com.lensyn.generator.handler.DtoNameHandler;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.internal.util.JavaBeansUtil;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.mybatis.generator.internal.util.JavaBeansUtil.getGetterMethodName;
import static org.mybatis.generator.internal.util.JavaBeansUtil.getSetterMethodName;

/**
 * Dto生成器
 * @author xiaob@lensysn.com
 * @date 2016/12/20
 * @see CUIDPlugin#generateDto(IntrospectedTable)
 */
public class GenerateDto {
    IntrospectedTable introspectedTable;
    DtoNameHandler dtoNameHandler;


    Set<MsgKey> msgKeys = new HashSet<MsgKey>();

    public GenerateDto(IntrospectedTable introspectedTable, DtoNameHandler dtoNameHandler) {
        this.introspectedTable = introspectedTable;
        this.dtoNameHandler = dtoNameHandler;
    }

    public TopLevelClass generate() {
        TopLevelClass dtoClass = new TopLevelClass(dtoNameHandler.dtoName(
                introspectedTable.getFullyQualifiedTable().getIntrospectedTableName()
        ));
        dtoClass.setVisibility(JavaVisibility.PUBLIC);

        List<IntrospectedColumn> introspectedColumns = introspectedTable.getPrimaryKeyColumns();

        for (IntrospectedColumn introspectedColumn : introspectedColumns) {
            generateField(introspectedColumn, dtoClass, false);
        }
        introspectedColumns = introspectedTable.getNonPrimaryKeyColumns();

        for (IntrospectedColumn introspectedColumn : introspectedColumns) {
            generateField(introspectedColumn, dtoClass, true);
        }


        NameUtils.addClassComment(dtoClass, introspectedTable, "Dto");
        return dtoClass;
    }

    ;

    void generateField(IntrospectedColumn introspectedColumn, TopLevelClass dtoClass, boolean hasValid) {

        FullyQualifiedJavaType fqjt = introspectedColumn
                .getFullyQualifiedJavaType();

        String property = introspectedColumn.getJavaProperty();

        Field field = new Field();
        field.setVisibility(JavaVisibility.PRIVATE);
        field.setType(fqjt);
        field.setName(property);
        ;
        if (!introspectedColumn.isNullable() && hasValid) {

            MsgKey msgKey = notEmptyMsgKey(dtoClass,introspectedColumn);

            dtoClass.addImportedType("org.hibernate.validator.constraints.NotEmpty");
            field.addAnnotation("@NotEmpty(message = \"{ " + msgKey.getKey() + " }\")");

            msgKeys.add(msgKey);
        }
        dtoClass.addField(field);
        dtoClass.addImportedType(field.getType());

        // Method method = getJavaBeansGetter(introspectedColumn, introspectedTable.getContext(), introspectedTable);

        Method settter = new Method();
        settter.setVisibility(JavaVisibility.PUBLIC);
        settter.setName(getSetterMethodName(property));
        settter.addParameter(new Parameter(fqjt, property));
        StringBuilder sb = new StringBuilder();
        sb.append("this."); //$NON-NLS-1$
        sb.append(property);
        sb.append(" = "); //$NON-NLS-1$
        sb.append(property);
        sb.append(';');
        settter.addBodyLine(sb.toString());
        dtoClass.addMethod(settter);

        Method getter = new Method();
        getter.setVisibility(JavaVisibility.PUBLIC);
        getter.setReturnType(fqjt);
        getter.setName(getGetterMethodName(property, fqjt));

        sb = new StringBuilder();
        sb.append("return "); //$NON-NLS-1$
        sb.append(property);
        sb.append(';');
        getter.addBodyLine(sb.toString());

        dtoClass.addMethod(getter);

    }

    /**
     * 不能为空的信息
     * @param dtoClass
     * @param introspectedColumn
     * @return
     */

    protected MsgKey notEmptyMsgKey(TopLevelClass dtoClass, IntrospectedColumn introspectedColumn){
        String msg = introspectedColumn.getRemarks();
        msg = (msg == null || msg.isEmpty()) ? introspectedColumn.getJavaProperty() : msg;

        String notMsg = msg + "不能为空";

        String msgKey =  NameUtils.cameToPropertiesKey(dtoClass.getType().getShortName());
        msgKey =  msgKey+NameUtils.cameToPropertiesKey(introspectedColumn.getJavaProperty());
        msgKey+="not.empty";

        return new MsgKey(msgKey,notMsg);

    }

    public Set<MsgKey> getMsgKeys() {
        return msgKeys;
    }
}
